#pragma once

#include "Widgets/Widget.h"
#include "Framework/Tickable.h"

#include "MouseDrag.m.h"

class RMouseWidget;

RENUM()
enum class EDragDirection
{
    Horizontal,
    Vertical,
    Both,
    Customized, // will not change the drag target's position,drag target is useless 
};

RCLASS()
class WHENGINE_API RMouseDrag : public RObject  
{
    ROBJECT
public:   
    RMouseDrag()=default;
    ~RMouseDrag();

    //need drag ? 
    RFIELD()
    TWidgetAttribute<bool> bIsEnabled=false;

    RFIELD()
    TWidgetAttribute<EDragDirection> Direction=EDragDirection::Both;

    // target widget that will be dragged , used when start to drag
    // can be null
    RFIELD()
    TWidgetAttribute<TSharedObjectPtr<RWidget>> Target;
    
    //limitation of target widget,obviously only valid when Target is not null
    RFIELD()
    TWidgetAttribute<float> TargetWidgetMinX=-std::numeric_limits<float>::max();
    RFIELD()
    TWidgetAttribute<float> TargetWidgetMaxX=std::numeric_limits<float>::max();
    RFIELD()
    TWidgetAttribute<float> TargetWidgetMinY=-std::numeric_limits<float>::max();
    RFIELD()
    TWidgetAttribute<float> TargetWidgetMaxY=std::numeric_limits<float>::max();

    

    bool ProcessMouseEvent(CWidgetTree* InTree,const SMouseButtonEvent& MouseEvent);

    TDelegate<void> OnDragStarted;
    TDelegate<void> OnDragEnded;
    TDelegate<void,const SVec2 & /*Total Move distance*/> OnDragMoved;

    bool IsDragging()
    {
        return bIsDragging;
    }
    
    void StopDrag();
    void StartDrag(CWidgetTree* InTree);

    TSharedObjectPtr<RMouseWidget>  GetOwnerMouse();

private:
    friend class RMouseWidget;

    //target widget in dragging, will be null if haven't set Target
    RWidgetWeakPtr CurrentTarget=nullptr;

    bool bIsDragging=false;

    //only valid when DetectingDrag
    float PressedTime=.0f;

    SVec2 StartDragWidgetPosition;
    SVec2 StartDragWidgetRelativePosition;
    SVec2 StartDragMousePosition;

};